package com.pocket.demo.business.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pocket.demo.base.api.PageResult;
import com.pocket.demo.base.exception.PocketValidateException;
import com.pocket.demo.business.controller.vo.UserPageReqVO;
import com.pocket.demo.business.controller.vo.UserRespVO;
import com.pocket.demo.business.controller.vo.UserSaveReqVO;
import com.pocket.demo.business.dao.UserMapper;
import com.pocket.demo.business.po.User;
import com.pocket.demo.business.service.UserService;
import com.pocket.demo.core.mq.rabbitMQ.RabbitMQConstant;
import jakarta.annotation.Resource;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validator;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.springframework.amqp.rabbit.core.RabbitMessagingTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Map;
import java.util.Set;
import java.util.UUID;


/**
 * 用户表(User)表服务实现类 【demo-MybatisPlus-1.5】
 *
 * @author makejava
 */
@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private static final Logger LOGGER = org.slf4j.LoggerFactory.getLogger(UserServiceImpl.class);

    @Resource private Validator validator;
    @Resource private RabbitMessagingTemplate rabbitMessagingTemplate;

    /**
     * 通过ID查询单条数据
     *
     * @param userId 主键
     * @return 实例对象
     */
    @Override
    public User queryById(String userId) {
        return this.getById(userId);
    }

    /**
     * 分页查询
     *
     * @param userPageReqVO 筛选条件
     * @return 查询结果
     */
    @Override
    public PageResult<User> queryByPage(UserPageReqVO userPageReqVO) {
        LambdaQueryWrapper<User> queryWrapper =  new LambdaQueryWrapper<User>()
                .like(StringUtils.isNotBlank(userPageReqVO.getNickName()), User::getNickName, userPageReqVO.getNickName())
                .like(StringUtils.isNotBlank(userPageReqVO.getRealName()), User::getRealName, userPageReqVO.getRealName())
                .eq(StringUtils.isNotBlank(userPageReqVO.getUserMail()), User::getUserMail, userPageReqVO.getUserMail())
                .eq(StringUtils.isNotBlank(userPageReqVO.getUserMobile()), User::getUserMobile, userPageReqVO.getUserMobile())
                .eq(StringUtils.isNotBlank(userPageReqVO.getSex()), User::getSex, userPageReqVO.getSex());
        return this.getBaseMapper().selectPage(userPageReqVO, userPageReqVO.getOrders(), queryWrapper);
    }

    /**
     * 新增数据
     *
     * @param userSaveReqVO 实例对象
     * @return 实例对象
     */
    @Override
    public User insert(UserSaveReqVO userSaveReqVO) {

        // 【demo-spring-validation-4】
        Set<ConstraintViolation<UserSaveReqVO>> result = validator.validate(userSaveReqVO);
        if (CollectionUtil.isNotEmpty(result)){
            throw new PocketValidateException(result, UserSaveReqVO.class);
        }

        User user = BeanUtil.toBean(userSaveReqVO, User.class);
        user.setUserRegTime(new Date());

        // TODO 用户密码加密
        // 接入 Spring Security 后，如果需要密码明文存储，需要在密码前加：{noop}
        this.save(user);

        // 【demo-MQ-rabbitMQ-5.2】

        Map<String, Object> headers = Map.of(RabbitMQConstant.CORRELATION_ID, UUID.randomUUID().toString());
        rabbitMessagingTemplate.convertAndSend(RabbitMQConstant.EXCHANGE_USER, RabbitMQConstant.ROUTING_KEY_USER_REGISTER_SUCCESS, BeanUtil.toBean(user, UserRespVO.class), headers);
        return user;
    }

    /**
     * 修改数据
     *
     * @param userSaveReqVO 实例对象
     * @return 实例对象
     */
    @Override
    public User edit(UserSaveReqVO userSaveReqVO) {
        User user = BeanUtil.toBean(userSaveReqVO, User.class);
        this.updateById(user);
        return this.queryById(userSaveReqVO.getUserId());
    }

    /**
     * 通过主键删除数据
     *
     * @param userId 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(String userId) {
        return this.removeById(userId);
    }

    /**
     * 根据用户唯一标识（登录名、邮箱、电话）获取用户信息
     * @param loginId
     * @return
     */
    @Override
    public User getByLoginNameOrEmailOrMobile(String loginId) {
        LambdaQueryWrapper<User> queryWrapper =  new LambdaQueryWrapper<User>()
                .eq(User::getNickName, loginId)
                .or().eq(User::getUserMail, loginId)
                .or().eq(User::getUserMobile, loginId);
        return this.getBaseMapper().selectOne(queryWrapper, true);
    }
}
